// Learn TypeScript:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

import EventTouch = cc.Event.EventTouch;
import Rocker from "./rocker";
import Hero from "./hero";
import {wxUtils} from "./wx/wxUtils";
import {MathUtils} from "./math/MathUtils";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Controls extends cc.Component {

  private _hero: cc.Node = null;

  @property(cc.Node)
  gameBoard: cc.Node = null;

  @property(cc.Node)
  rocker: cc.Node = null;

  @property(cc.Sprite)
  subContext: cc.Sprite = null

  heroScript: Hero = null;

  private rockerComponent: Rocker;
  private size: cc.Size;
  private texture: cc.Texture2D = new cc.Texture2D()

  onLoad() {
    this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)
    this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this)
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this)
    this.rockerComponent = this.rocker.getComponent(Rocker) as Rocker
    this.size = cc.view.getVisibleSize();
  }

  set hero(value: cc.Node) {
    this._hero = value;
    this.heroScript = this._hero.getComponent(Hero);
  }

  update() {
    this.texture.initWithElement(wxUtils.getSharedCanvas())
    this.texture.handleLoadedTexture();
    this.subContext.spriteFrame = new cc.SpriteFrame(this.texture)
  }

  private startX: number = 0;
  private startY: number = 0;
  private rockeyTouchId: number = -1;

  private onTouchStart(e: EventTouch) {
    if (this.heroScript.heroMove || (e.getLocationX() > this.size.width / 2 || e.getLocationY() > this.size.height / 2)) {
      return;
    }
    const id = e.getTouches()[0].getID();
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    const startX = e.getLocationX();
    const startY = e.getLocationY();
    this.rockeyTouchId = id;
    this.startX = startX;
    this.startY = startY;
    this.rockerComponent.active(this.startX, this.startY);
    this.onTouchStartRecord(id, startX, startY);
  }

  private onTouchMove(e: EventTouch) {
    if (this.rockeyTouchId !== e.touch.getID()) {
      return;
    }
    this.onTouchMoveRecord(e.getLocationX(), e.getLocationY())
  }

  private onTouchEnd(e: EventTouch) {
    if (this.rockeyTouchId !== e.touch.getID()) {
      return;
    }
    this.onTouchEndRecord();
  }

  public onTouchStartRecord(id: number, startX: number, startY: number) {
    // frameUtils.recordTouchStart(id, startX, startY);
    this.rockeyTouchId = id
  }

  public onTouchMoveRecord(locationX: number, locationY: number) {
    // frameUtils.recordTouchMove(locationX, locationY);
    const deltaX = locationX - this.startX
    const deltaY = locationY - this.startY
    this.rockerComponent.onTouchMove(deltaX, deltaY)
    if (deltaX * deltaX + deltaY * deltaY < 100) {
      this.heroScript.heroMove = false;
      return;
    }
    this.heroScript.heroMove = true;
    const angle = Math.atan2(deltaX, deltaY);
    let targetAngle = angle * 180 / MathUtils.PI;
    if (targetAngle < 0) {
      targetAngle += 360
    }
    this.heroScript.moveToTargetAngle(Math.floor(targetAngle));
  }

  public onTouchEndRecord() {
    // frameUtils.recordTouchEnd();
    this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this)
    this.heroScript.heroMove = false;
    this.startY = 0;
    this.startX = 0;
    this.rockerComponent.deactive();
  }

  onDestroy() {
    this.node.targetOff(this.node)
  }
}
